home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 January / macformat-020.iso / Shareware City / Developers / OutOfPhase1.01Source / OutOfPhase Folder / CalculatorWindow.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-01  |  25.9 KB  |  874 lines  |  [TEXT/KAHL]

  1. /* CalculatorWindow.c */
  2. /*****************************************************************************/
  3. /*                                                                           */
  4. /*    Out Of Phase:  Digital Music Synthesis on General Purpose Computers    */
  5. /*    Copyright (C) 1994  Thomas R. Lawrence                                 */
  6. /*                                                                           */
  7. /*    This program is free software; you can redistribute it and/or modify   */
  8. /*    it under the terms of the GNU General Public License as published by   */
  9. /*    the Free Software Foundation; either version 2 of the License, or      */
  10. /*    (at your option) any later version.                                    */
  11. /*                                                                           */
  12. /*    This program is distributed in the hope that it will be useful,        */
  13. /*    but WITHOUT ANY WARRANTY; without even the implied warranty of         */
  14. /*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
  15. /*    GNU General Public License for more details.                           */
  16. /*                                                                           */
  17. /*    You should have received a copy of the GNU General Public License      */
  18. /*    along with this program; if not, write to the Free Software            */
  19. /*    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              */
  20. /*                                                                           */
  21. /*    Thomas R. Lawrence can be reached at tomlaw@world.std.com.             */
  22. /*                                                                           */
  23. /*****************************************************************************/
  24.  
  25. #include "MiscInfo.h"
  26. #include "Audit.h"
  27. #include "Debug.h"
  28. #include "Definitions.h"
  29.  
  30. #include "CalculatorWindow.h"
  31. #include "Screen.h"
  32. #include "TextEdit.h"
  33. #include "Memory.h"
  34. #include "MainWindowStuff.h"
  35. #include "GrowIcon.h"
  36. #include "Main.h"
  37. #include "SimpleButton.h"
  38. #include "Alert.h"
  39. #include "CodeCenter.h"
  40. #include "PcodeStack.h"
  41. #include "PcodeSystem.h"
  42. #include "DataMunging.h"
  43. #include "Numbers.h"
  44. #include "FixedPoint.h"
  45. #include "WindowDispatcher.h"
  46. #include "GlobalWindowMenuList.h"
  47. #include "FunctionCode.h"
  48. #include "CompilerRoot.h"
  49. #include "PcodeDisassembly.h"
  50. #include "DisassemblyWindow.h"
  51.  
  52.  
  53. #define WINDOWLEFT (30)
  54. #define WINDOWTOP (30)
  55. #define WINDOWWIDTH (450)
  56. #define WINDOWHEIGHT (200)
  57.  
  58. #define BUTTONLEFT (10)
  59. #define BUTTONTOP (2)
  60. #define BUTTONWIDTH (120)
  61. #define BUTTONHEIGHT (19)
  62.  
  63. struct CalcWindowRec
  64.     {
  65.         MainWindowRec*            MainWindow;
  66.         CodeCenterRec*            CodeCenter;
  67.  
  68.         WinType*                        ScreenID;
  69.         GenericWindowRec*        MyGenericWindow; /* how the window event dispatcher knows us */
  70.         MenuItemType*                MyMenuItem;
  71.         TextEditRec*                Editor;
  72.         long                                LastLine;
  73.         SimpleButtonRec*        EvalButton;
  74.     };
  75.  
  76.  
  77. /* create a new calculator window.  the caller is responsible for registering the */
  78. /* new calculator with the main window. */
  79. CalcWindowRec*            NewCalculatorWindow(struct MainWindowRec* MainWindow,
  80.                                             struct CodeCenterRec* CodeCenter)
  81.     {
  82.         CalcWindowRec*        Window;
  83.  
  84.         CheckPtrExistence(MainWindow);
  85.         CheckPtrExistence(CodeCenter);
  86.         Window = (CalcWindowRec*)AllocPtrCanFail(sizeof(CalcWindowRec),"CalcWindowRec");
  87.         if (Window == NIL)
  88.             {
  89.              FailurePoint1:
  90.                 return NIL;
  91.             }
  92.         Window->MainWindow = MainWindow;
  93.         Window->CodeCenter = CodeCenter;
  94.         Window->ScreenID = MakeNewWindow(eDocumentWindow,eWindowClosable,
  95.             eWindowZoomable,eWindowResizable,WINDOWLEFT,WINDOWTOP,WINDOWWIDTH,WINDOWHEIGHT,
  96.             (void (*)(void*))&CalculatorWindowUpdator,Window);
  97.         if (Window->ScreenID == 0)
  98.             {
  99.              FailurePoint2:
  100.                 ReleasePtr((char*)Window);
  101.                 goto FailurePoint1;
  102.             }
  103.         SetWindowName(Window->ScreenID,"Calculator");
  104.         Window->Editor = NewTextEdit(Window->ScreenID,eTEVScrollBar | eTEHScrollBar,
  105.             GetMonospacedFont(),9,-1,(2 * BUTTONTOP) + BUTTONHEIGHT,WINDOWWIDTH + 2,
  106.             WINDOWHEIGHT + 1 - ((2 * BUTTONTOP) + BUTTONHEIGHT));
  107.         if (Window->Editor == NIL)
  108.             {
  109.              FailurePoint3:
  110.                 KillWindow(Window->ScreenID);
  111.                 goto FailurePoint2;
  112.             }
  113.         Window->LastLine = 0;
  114.         Window->EvalButton = NewSimpleButton(Window->ScreenID,"Evaluate",
  115.             BUTTONLEFT,BUTTONTOP,BUTTONWIDTH,BUTTONHEIGHT);
  116.         if (Window->EvalButton == NIL)
  117.             {
  118.              FailurePoint4:
  119.                 DisposeTextEdit(Window->Editor);
  120.                 goto FailurePoint3;
  121.             }
  122.         Window->MyGenericWindow = CheckInNewWindow(Window->ScreenID,Window,
  123.             (void (*)(void*,MyBoolean,OrdType,OrdType,ModifierFlags))&CalculatorWindowDoIdle,
  124.             (void (*)(void*))&CalculatorWindowBecomeActive,
  125.             (void (*)(void*))&CalculatorWindowBecomeInactive,
  126.             (void (*)(void*))&CalculatorWindowJustResized,
  127.             (void (*)(OrdType,OrdType,ModifierFlags,void*))&CalculatorWindowDoMouseDown,
  128.             (void (*)(unsigned char,ModifierFlags,void*))&CalculatorWindowDoKeyDown,
  129.             (void (*)(void*))&CalculatorWindowClose,
  130.             (void (*)(void*))&CalculatorWindowMenuSetup,
  131.             (void (*)(void*,MenuItemType*))&CalculatorWindowDoMenuCommand);
  132.         if (Window->MyGenericWindow == NIL)
  133.             {
  134.              FailurePoint5:
  135.                 DisposeSimpleButton(Window->EvalButton);
  136.                 goto FailurePoint4;
  137.             }
  138.         Window->MyMenuItem = MakeNewMenuItem(mmWindowMenu,"Calculator",0);
  139.         if (Window->MyMenuItem == NIL)
  140.             {
  141.              FailurePoint6:
  142.                 CheckOutDyingWindow(Window->MyGenericWindow);
  143.                 goto FailurePoint5;
  144.             }
  145.         if (!RegisterWindowMenuItem(Window->MyMenuItem,(void (*)(void*))&ActivateThisWindow,
  146.             Window->ScreenID))
  147.             {
  148.              FailurePoint7:
  149.                 KillMenuItem(Window->MyMenuItem);
  150.                 goto FailurePoint6;
  151.             }
  152.         SetTextEditAutoIndent(Window->Editor,True);
  153.         SetTextEditTabSize(Window->Editor,MainWindowGetTabSize(MainWindow));
  154.         return Window;
  155.     }
  156.  
  157.  
  158. /* dispose of a calculator window.  the calculator notifies the main window that */
  159. /* owns it. */
  160. void                                DisposeCalculatorWindow(CalcWindowRec* Window)
  161.     {
  162.         CheckPtrExistence(Window);
  163.         DeregisterWindowMenuItem(Window->MyMenuItem);
  164.         KillMenuItem(Window->MyMenuItem);
  165.         CheckOutDyingWindow(Window->MyGenericWindow);
  166.         DisposeSimpleButton(Window->EvalButton);
  167.         DisposeTextEdit(Window->Editor);
  168.         KillWindow(Window->ScreenID);
  169.         ReleasePtr((char*)Window);
  170.     }
  171.  
  172.  
  173. void                                CalculatorWindowDoIdle(CalcWindowRec* Window,
  174.                                             MyBoolean CheckCursorFlag, OrdType XLoc, OrdType YLoc,
  175.                                             ModifierFlags Modifiers)
  176.     {
  177.         CheckPtrExistence(Window);
  178.         TextEditUpdateCursor(Window->Editor);
  179.         if (CheckCursorFlag)
  180.             {
  181.                 if (TextEditIBeamTest(Window->Editor,XLoc,YLoc))
  182.                     {
  183.                         SetIBeamCursor();
  184.                     }
  185.                  else
  186.                     {
  187.                         SetArrowCursor();
  188.                     }
  189.             }
  190.     }
  191.  
  192.  
  193. void                                CalculatorWindowBecomeActive(CalcWindowRec* Window)
  194.     {
  195.         OrdType                        XSize;
  196.         OrdType                        YSize;
  197.  
  198.         CheckPtrExistence(Window);
  199.         EnableTextEditSelection(Window->Editor);
  200.         XSize = GetWindowWidth(Window->ScreenID);
  201.         YSize = GetWindowHeight(Window->ScreenID);
  202.         SetClipRect(Window->ScreenID,XSize - 15,YSize - 15,XSize,YSize);
  203.         DrawBitmap(Window->ScreenID,XSize-15,YSize-15,GetGrowIcon(True/*enablegrowicon*/));
  204.     }
  205.  
  206.  
  207. void                                CalculatorWindowBecomeInactive(CalcWindowRec* Window)
  208.     {
  209.         OrdType                        XSize;
  210.         OrdType                        YSize;
  211.  
  212.         CheckPtrExistence(Window);
  213.         DisableTextEditSelection(Window->Editor);
  214.         XSize = GetWindowWidth(Window->ScreenID);
  215.         YSize = GetWindowHeight(Window->ScreenID);
  216.         SetClipRect(Window->ScreenID,XSize - 15,YSize - 15,XSize,YSize);
  217.         DrawBitmap(Window->ScreenID,XSize-15,YSize-15,GetGrowIcon(False/*disablegrowicon*/));
  218.     }
  219.  
  220.  
  221. void                                CalculatorWindowJustResized(CalcWindowRec* Window)
  222.     {
  223.         OrdType                        XSize;
  224.         OrdType                        YSize;
  225.  
  226.         CheckPtrExistence(Window);
  227.         XSize = GetWindowWidth(Window->ScreenID);
  228.         YSize = GetWindowHeight(Window->ScreenID);
  229.         SetClipRect(Window->ScreenID,0,0,XSize,YSize);
  230.         DrawBoxErase(Window->ScreenID,0,0,XSize,YSize);
  231.         SetTextEditPosition(Window->Editor,-1,(2 * BUTTONTOP) + BUTTONHEIGHT,
  232.             XSize + 2,YSize + 1 - ((2 * BUTTONTOP) + BUTTONHEIGHT));
  233.     }
  234.  
  235.  
  236. void                                CalculatorWindowDoMouseDown(OrdType XLoc, OrdType YLoc,
  237.                                             ModifierFlags Modifiers, CalcWindowRec* Window)
  238.     {
  239.         CheckPtrExistence(Window);
  240.         if ((XLoc >= GetWindowWidth(Window->ScreenID) - 15)
  241.             && (XLoc < GetWindowWidth(Window->ScreenID))
  242.             && (YLoc >= GetWindowHeight(Window->ScreenID) - 15)
  243.             && (YLoc < GetWindowHeight(Window->ScreenID)))
  244.             {
  245.                 UserGrowWindow(Window->ScreenID,XLoc,YLoc);
  246.                 CalculatorWindowJustResized(Window);
  247.             }
  248.         else if (TextEditHitTest(Window->Editor,XLoc,YLoc))
  249.             {
  250.                 TextEditDoMouseDown(Window->Editor,XLoc,YLoc,Modifiers);
  251.             }
  252.         else if (SimpleButtonHitTest(Window->EvalButton,XLoc,YLoc))
  253.             {
  254.                 if (SimpleButtonMouseDown(Window->EvalButton,XLoc,YLoc,NIL,NIL))
  255.                     {
  256.                         CalculatorWindowDoCalculation(Window);
  257.                     }
  258.             }
  259.     }
  260.  
  261.  
  262. void                                CalculatorWindowDoKeyDown(unsigned char KeyCode,
  263.                                             ModifierFlags Modifiers, CalcWindowRec* Window)
  264.     {
  265.         CheckPtrExistence(Window);
  266.         TextEditDoKeyPressed(Window->Editor,KeyCode,Modifiers);
  267.     }
  268.  
  269.  
  270. void                                CalculatorWindowClose(CalcWindowRec* Window)
  271.     {
  272.         CheckPtrExistence(Window);
  273.         /* notification of closing is here and not in dispose because FunctionWindow */
  274.         /* calls dispose, so it knows that we are dying, but this routine handles */
  275.         /* a user close, which FunctionWindow doesn't know about */
  276.         MainWindowCalculatorClosingNotify(Window->MainWindow,Window);
  277.         DisposeCalculatorWindow(Window);
  278.     }
  279.  
  280.  
  281. void                                CalculatorWindowUpdator(CalcWindowRec* Window)
  282.     {
  283.         OrdType            XSize;
  284.         OrdType            YSize;
  285.  
  286.         CheckPtrExistence(Window);
  287.         TextEditFullRedraw(Window->Editor);
  288.         RedrawSimpleButton(Window->EvalButton);
  289.         XSize = GetWindowWidth(Window->ScreenID);
  290.         YSize = GetWindowHeight(Window->ScreenID);
  291.         SetClipRect(Window->ScreenID,XSize - 15,YSize - 15,XSize,YSize);
  292.         DrawBitmap(Window->ScreenID,XSize-15,YSize-15,
  293.             GetGrowIcon(Window->MyGenericWindow == GetCurrentWindowID()));
  294.     }
  295.  
  296.  
  297. void                                CalculatorWindowMenuSetup(CalcWindowRec* Window)
  298.     {
  299.         CheckPtrExistence(Window);
  300.         MainWindowEnableGlobalMenus(Window->MainWindow);
  301.         EnableMenuItem(mPaste);
  302.         ChangeItemName(mPaste,"Paste Text");
  303.         if (TextEditIsThereValidSelection(Window->Editor))
  304.             {
  305.                 EnableMenuItem(mCut);
  306.                 ChangeItemName(mCut,"Cut Text");
  307.                 EnableMenuItem(mCopy);
  308.                 ChangeItemName(mCopy,"Copy Text");
  309.                 EnableMenuItem(mClear);
  310.                 ChangeItemName(mClear,"Clear Text");
  311.             }
  312.         EnableMenuItem(mShiftLeft);
  313.         EnableMenuItem(mShiftRight);
  314.         EnableMenuItem(mBalanceParens);
  315.         EnableMenuItem(mSelectAll);
  316.         ChangeItemName(mSelectAll,"Select All Text");
  317.         if (TextEditCanWeUndo(Window->Editor))
  318.             {
  319.                 EnableMenuItem(mUndo);
  320.                 ChangeItemName(mUndo,"Undo Text Change");
  321.             }
  322.         ChangeItemName(mCloseFile,"Close Calculator");
  323.         EnableMenuItem(mCloseFile);
  324.         EnableMenuItem(mEvaluateCalc);
  325.         SetItemCheckmark(Window->MyMenuItem);
  326.         EnableMenuItem(mDisassembleFunction);
  327.     }
  328.  
  329.  
  330. void                                CalculatorWindowDoMenuCommand(CalcWindowRec* Window,
  331.                                             MenuItemType* MenuItem)
  332.     {
  333.         CheckPtrExistence(Window);
  334.         if (MainWindowDoGlobalMenuItem(Window->MainWindow,MenuItem))
  335.             {
  336.             }
  337.         else if (MenuItem == mPaste)
  338.             {
  339.                 TextEditDoMenuPaste(Window->Editor);
  340.             }
  341.         else if (MenuItem == mCut)
  342.             {
  343.                 TextEditDoMenuCut(Window->Editor);
  344.             }
  345.         else if (MenuItem == mCopy)
  346.             {
  347.                 TextEditDoMenuCopy(Window->Editor);
  348.             }
  349.         else if (MenuItem == mClear)
  350.             {
  351.                 TextEditDoMenuClear(Window->Editor);
  352.             }
  353.         else if (MenuItem == mSelectAll)
  354.             {
  355.                 TextEditDoMenuSelectAll(Window->Editor);
  356.             }
  357.         else if (MenuItem == mUndo)
  358.             {
  359.                 TextEditDoMenuUndo(Window->Editor);
  360.             }
  361.         else if (MenuItem == mCloseFile)
  362.             {
  363.                 CalculatorWindowClose(Window);
  364.             }
  365.         else if (MenuItem == mShiftLeft)
  366.             {
  367.                 TextEditShiftSelectionLeftOneTab(Window->Editor);
  368.             }
  369.         else if (MenuItem == mShiftRight)
  370.             {
  371.                 TextEditShiftSelectionRightOneTab(Window->Editor);
  372.             }
  373.         else if (MenuItem == mBalanceParens)
  374.             {
  375.                 TextEditBalanceParens(Window->Editor);
  376.             }
  377.         else if (MenuItem == mEvaluateCalc)
  378.             {
  379.                 CalculatorWindowDoCalculation(Window);
  380.             }
  381.         else if (MenuItem == mDisassembleFunction)
  382.             {
  383.                 char*                                Blob;
  384.                 PcodeRec*                        FuncCode;
  385.                 CompileErrors                Error;
  386.                 long                                LineNumber;
  387.                 DataTypes                        ReturnType;
  388.                 char*                                DisassemblyText;
  389.  
  390.                 /* prepare the text blob to be evaluated */
  391.                 if (!TextEditIsThereValidSelection(Window->Editor))
  392.                     {
  393.                         if (Window->LastLine > GetTextEditNumLines(Window->Editor))
  394.                             {
  395.                                 Window->LastLine = GetTextEditNumLines(Window->Editor);
  396.                             }
  397.                         SetTextEditSelection(Window->Editor,Window->LastLine,0,
  398.                             GetTextEditNumLines(Window->Editor),0);
  399.                     }
  400.                 Blob = TextEditGetSelection(Window->Editor);
  401.                 if (Blob == NIL)
  402.                     {
  403.                      FailurePoint1:
  404.                         AlertHalt("There is not enough memory available to compile "
  405.                             "the expression.",NIL);
  406.                         return;
  407.                     }
  408.  
  409.                 /* perform compilation */
  410.                 EXECUTE(FuncCode = NIL;)
  411.                 Error = CompileSpecialFunction(NIL/*no arguments*/,0/*noargs*/,&LineNumber,
  412.                     &ReturnType,Blob/*text*/,&FuncCode);
  413.                 ReleasePtr(Blob);
  414.                 if (Error != eCompileNoError)
  415.                     {
  416.                         ERROR(FuncCode != NIL,PRERR(ForceAbort,"CalculatorWindowDoMenuCommand:  "
  417.                             "compile failed, but function is not NIL."));
  418.                         SetTextEditSelection(Window->Editor,
  419.                             GetTextEditSelectStartLine(Window->Editor) + LineNumber,0,
  420.                             GetTextEditSelectStartLine(Window->Editor) + LineNumber + 1,0);
  421.                         TextEditShowSelection(Window->Editor);
  422.                         AlertHalt("A compile error occurred:  _",GetCompileErrorString(Error));
  423.                         return;
  424.                     }
  425.  
  426.                 /* obtain the disassembly */
  427.                 DisassemblyText = DisassemblePcode(FuncCode,'\x0a');
  428.                 DisposePcode(FuncCode);
  429.                 if (DisassemblyText == NIL)
  430.                     {
  431.                         AlertHalt("There is not enough memory available to disassemble "
  432.                             "the expression.",NIL);
  433.                         return;
  434.                     }
  435.  
  436.                 /* show it */
  437.                 if (NewDisassemblyWindow(DisassemblyText,Window->MainWindow) == NIL)
  438.                     {
  439.                         AlertHalt("There is not enough memory available to "
  440.                             "show the disassembly window.",NIL);
  441.                     }
  442.                 ReleasePtr(DisassemblyText);
  443.             }
  444.         else
  445.             {
  446.                 EXECUTE(PRERR(AllowResume,"CalculatorWindowDoMenuCommand:  unknown menu command"));
  447.             }
  448.     }
  449.  
  450.  
  451. /* perform evaluation.  if there is a selection, then evaluate */
  452. /* the selection, otherwise evaluate from last point */
  453. void                                CalculatorWindowDoCalculation(CalcWindowRec* Window)
  454.     {
  455.         char*                                Blob;
  456.         PcodeRec*                        FuncCode;
  457.         CompileErrors                Error;
  458.         long                                LineNumber;
  459.         DataTypes                        ReturnType;
  460.         ParamStackRec*            ParamList;
  461.         EvalErrors                    OtherError;
  462.         OpcodeRec*                    ErrorOpcode;
  463.         long                                OffendingInstruction;
  464.         char*                                Number;
  465.         char*                                Statement;
  466.         MyBoolean                        MemoryErrorOccurred;
  467.  
  468.         CheckPtrExistence(Window);
  469.  
  470.         /* bring the world up to date */
  471.         if (!MainWindowMakeUpToDateFunctions(Window->MainWindow))
  472.             {
  473.                 return;
  474.             }
  475.  
  476.         /* prepare the text blob to be evaluated */
  477.         if (!TextEditIsThereValidSelection(Window->Editor))
  478.             {
  479.                 if (Window->LastLine > GetTextEditNumLines(Window->Editor))
  480.                     {
  481.                         Window->LastLine = GetTextEditNumLines(Window->Editor);
  482.                     }
  483.                 SetTextEditSelection(Window->Editor,Window->LastLine,0,
  484.                     GetTextEditNumLines(Window->Editor),0);
  485.             }
  486.         Blob = TextEditGetSelection(Window->Editor);
  487.         if (Blob == NIL)
  488.             {
  489.              FailurePoint1:
  490.                 AlertHalt("There is not enough memory available to compile the expression.",NIL);
  491.                 return;
  492.             }
  493.  
  494.         /* perform compilation */
  495.         EXECUTE(FuncCode = NIL;)
  496.         Error = CompileSpecialFunction(NIL/*no arguments*/,0/*noargs*/,&LineNumber,
  497.             &ReturnType,Blob/*text*/,&FuncCode);
  498.         ReleasePtr(Blob);
  499.         if (Error != eCompileNoError)
  500.             {
  501.                 ERROR(FuncCode != NIL,PRERR(ForceAbort,
  502.                     "CalculatorWindowDoCalculation:  compile failed, but function is not NIL."));
  503.                 SetTextEditSelection(Window->Editor,GetTextEditSelectStartLine(Window->Editor)
  504.                     + LineNumber,0,GetTextEditSelectStartLine(Window->Editor) + LineNumber + 1,0);
  505.                 TextEditShowSelection(Window->Editor);
  506.                 AlertHalt("A compile error occurred:  _",GetCompileErrorString(Error));
  507.                 return;
  508.             }
  509.  
  510.         /* try to evaluate the code */
  511.         ParamList = NewParamStack();
  512.         if (ParamList == NIL)
  513.             {
  514.              SecondFailurePoint1:
  515.                 DisposePcode(FuncCode);
  516.                 AlertHalt("There is not enough memory available to evaluate the expression.",NIL);
  517.                 return;
  518.             }
  519.         /* add a space for the return value */
  520.         if (!AddIntegerToStack(ParamList,0))
  521.             {
  522.              SecondFailurePoint2:
  523.                 goto SecondFailurePoint1;
  524.             }
  525.         /* executing the actual code */
  526.         OtherError = EvaluatePcode(ParamList,FuncCode,
  527.             Window->CodeCenter,&ErrorOpcode,&OffendingInstruction,Window->MainWindow,
  528.             &MainWindowGetSampleLeftCopy,&MainWindowGetSampleRightCopy,
  529.             &MainWindowGetSampleMonoCopy,&MainWindowGetWaveTableFrameCount,
  530.             &MainWindowGetWaveTableTableCount,&MainWindowGetWaveTableArray);
  531.         if (OtherError != eEvalNoError)
  532.             {
  533.                 char*                    FuncNameString;
  534.                 MyBoolean            SuccessFlag;
  535.  
  536.                 /* present error message */
  537.                 SuccessFlag = False;
  538.                 if (GetOpcodeFromPcode(FuncCode) == ErrorOpcode)
  539.                     {
  540.                         /* our function, not a library function */
  541.                         FuncNameString = StringToBlockCopy("<anonymous>");
  542.                     }
  543.                  else
  544.                     {
  545.                         /* it is a library function, so look it up */
  546.                         FuncNameString = StringToBlockCopy(GetFunctionName(
  547.                             GetFunctionFromOpcode(Window->CodeCenter,ErrorOpcode)));
  548.                     }
  549.                 if (FuncNameString != NIL)
  550.                     {
  551.                         char*                    Key;
  552.  
  553.                         Key = StringToBlockCopy("_");
  554.                         if (Key != NIL)
  555.                             {
  556.                                 char*                    BaseMessage;
  557.  
  558.                                 BaseMessage = StringFromRaw("Error in function _, instruction _:  _");
  559.                                 if (BaseMessage != NIL)
  560.                                     {
  561.                                         char*                    FixedMessage1;
  562.  
  563.                                         FixedMessage1 = ReplaceBlockCopy(BaseMessage,Key,FuncNameString);
  564.                                         if (FixedMessage1 != NIL)
  565.                                             {
  566.                                                 char*                    NumberStr;
  567.  
  568.                                                 NumberStr = IntegerToString(OffendingInstruction);
  569.                                                 if (NumberStr != NIL)
  570.                                                     {
  571.                                                         char*                    FixedMessage2;
  572.  
  573.                                                         FixedMessage2 = ReplaceBlockCopy(FixedMessage1,Key,NumberStr);
  574.                                                         if (FixedMessage2 != NIL)
  575.                                                             {
  576.                                                                 AlertHalt(FixedMessage2,GetPcodeErrorMessage(OtherError));
  577.                                                                 SuccessFlag = True;
  578.                                                                 ReleasePtr(FixedMessage2);
  579.                                                             }
  580.                                                         ReleasePtr(NumberStr);
  581.                                                     }
  582.                                                 ReleasePtr(FixedMessage1);
  583.                                             }
  584.                                         ReleasePtr(BaseMessage);
  585.                                     }
  586.                                 ReleasePtr(Key);
  587.                             }
  588.                         ReleasePtr(FuncNameString);
  589.                     }
  590.                 if (!SuccessFlag)
  591.                     {
  592.                         AlertHalt("There is not enough memory available to show "
  593.                             "the compile error message.",NIL);
  594.                     }
  595.                 DisposeParamStack(ParamList);
  596.                 DisposePcode(FuncCode);
  597.                 return;
  598.             }
  599.  
  600.         /* add new data to window */
  601.         MemoryErrorOccurred = False;
  602.         TextEditAppendLineInteraction(Window->Editor,NIL);
  603.         switch (ReturnType)
  604.             {
  605.                 default:
  606.                     EXECUTE(PRERR(ForceAbort,"CalculatorWindowDoCalculation:  unknown type"));
  607.                     break;
  608.                 case eBoolean:
  609.                     /* prepare value */
  610.                     if (GetStackInteger(ParamList,0) != 0)
  611.                         {
  612.                             Number = StringToBlockCopy("true");
  613.                         }
  614.                      else
  615.                         {
  616.                             Number = StringToBlockCopy("false");
  617.                         }
  618.                     Statement = StringToBlockCopy("returns boolean:  _");
  619.                     /* put value in editor */
  620.                  ScalarMakePoint:
  621.                     if (Number != NIL)
  622.                         {
  623.                             if (Statement != NIL)
  624.                                 {
  625.                                     char*                Key;
  626.  
  627.                                     Key = StringToBlockCopy("_");
  628.                                     if (Key != NIL)
  629.                                         {
  630.                                             char*                Fixer;
  631.  
  632.                                             Fixer = ReplaceBlockCopy(Statement,Key,Number);
  633.                                             if (Fixer != NIL)
  634.                                                 {
  635.                                                     TextEditAppendLineInteraction(Window->Editor,Fixer);
  636.                                                     ReleasePtr(Fixer);
  637.                                                 }
  638.                                              else
  639.                                                 {
  640.                                                     MemoryErrorOccurred = True;
  641.                                                 }
  642.                                             ReleasePtr(Key);
  643.                                         }
  644.                                      else
  645.                                         {
  646.                                             MemoryErrorOccurred = True;
  647.                                         }
  648.                                 }
  649.                              else
  650.                                 {
  651.                                     MemoryErrorOccurred = True;
  652.                                 }
  653.                         }
  654.                      else
  655.                         {
  656.                             MemoryErrorOccurred = True;
  657.                         }
  658.                     /* dispose values */
  659.                     if (Number != NIL)
  660.                         {
  661.                             ReleasePtr(Number);
  662.                         }
  663.                     if (Statement != NIL)
  664.                         {
  665.                             ReleasePtr(Statement);
  666.                         }
  667.                     break;
  668.                 case eInteger:
  669.                     Number = IntegerToString(GetStackInteger(ParamList,0));
  670.                     Statement = StringToBlockCopy("returns integer:  _");
  671.                     goto ScalarMakePoint;
  672.                 case eFixed:
  673.                     Number = LongDoubleToString(
  674.                         largefixed2double(GetStackInteger(ParamList,0)),11,1e-9,1e6);
  675.                     Statement = StringToBlockCopy("returns fixed:  _");
  676.                     goto ScalarMakePoint;
  677.                 case eFloat:
  678.                     Number = LongDoubleToString(GetStackFloat(ParamList,0),7,1e-4,1e6);
  679.                     Statement = StringToBlockCopy("returns float:  _");
  680.                     goto ScalarMakePoint;
  681.                 case eDouble:
  682.                     Number = LongDoubleToString(GetStackLongDouble(ParamList,0),15,1e-4,1e6);
  683.                     Statement = StringToBlockCopy("returns double:  _");
  684.                     goto ScalarMakePoint;
  685.                 case eArrayOfBoolean:
  686.                     Statement = StringToBlockCopy("returns array of boolean:");
  687.                     goto ArrayMakePoint;
  688.                 case eArrayOfInteger:
  689.                     Statement = StringToBlockCopy("returns array of integer:");
  690.                     goto ArrayMakePoint;
  691.                 case eArrayOfFixed:
  692.                     Statement = StringToBlockCopy("returns array of fixed:");
  693.                     goto ArrayMakePoint;
  694.                 case eArrayOfFloat:
  695.                     Statement = StringToBlockCopy("returns array of float:");
  696.                     goto ArrayMakePoint;
  697.                 case eArrayOfDouble:
  698.                     /* construct statement */
  699.                     Statement = StringToBlockCopy("returns array of double:");
  700.                  ArrayMakePoint:
  701.                     if (Statement != NIL)
  702.                         {
  703.                             void*                    Array;
  704.  
  705.                             TextEditAppendLineInteraction(Window->Editor,Statement);
  706.                             ReleasePtr(Statement);
  707.                             Array = GetStackArray(ParamList,0);
  708.                             if (Array == NIL)
  709.                                 {
  710.                                     char*                    Thang;
  711.  
  712.                                     Thang = StringToBlockCopy("NIL");
  713.                                     if (Thang != NIL)
  714.                                         {
  715.                                             TextEditAppendLineInteraction(Window->Editor,Thang);
  716.                                             ReleasePtr(Thang);
  717.                                         }
  718.                                      else
  719.                                         {
  720.                                             MemoryErrorOccurred = True;
  721.                                         }
  722.                                 }
  723.                              else
  724.                                 {
  725.                                     long                    Scan;
  726.                                     long                    ElementSize;
  727.                                     long                    Limit;
  728.  
  729.                                     switch (ReturnType)
  730.                                         {
  731.                                             case eArrayOfBoolean:
  732.                                                 ElementSize = sizeof(char);
  733.                                                 break;
  734.                                             case eArrayOfInteger:
  735.                                                 ElementSize = sizeof(long);
  736.                                                 break;
  737.                                             case eArrayOfFixed:
  738.                                                 ElementSize = sizeof(largefixedsigned);
  739.                                                 break;
  740.                                             case eArrayOfFloat:
  741.                                                 ElementSize = sizeof(float);
  742.                                                 break;
  743.                                             case eArrayOfDouble:
  744.                                                 ElementSize = sizeof(double);
  745.                                                 break;
  746.                                             default:
  747.                                                 EXECUTE(PRERR(ForceAbort,
  748.                                                     "CalculatorWindowDoCalculation:  type filter failure"));
  749.                                                 break;
  750.                                         }
  751.                                     Limit = PtrSize((char*)Array) / ElementSize;
  752.                                     for (Scan = 0; (Scan < Limit) && !MemoryErrorOccurred
  753.                                         && !RelinquishCPUJudiciouslyCheckCancel(); Scan += 1)
  754.                                         {
  755.                                             char*                    LineNum;
  756.  
  757.                                             LineNum = IntegerToString(Scan);
  758.                                             if (LineNum != NIL)
  759.                                                 {
  760.                                                     char*                    Data;
  761.  
  762.                                                     switch (ReturnType)
  763.                                                         {
  764.                                                             case eArrayOfBoolean:
  765.                                                                 if (((char*)Array)[Scan])
  766.                                                                     {
  767.                                                                         Data = StringToBlockCopy("true");
  768.                                                                     }
  769.                                                                  else
  770.                                                                     {
  771.                                                                         Data = StringToBlockCopy("false");
  772.                                                                     }
  773.                                                                 break;
  774.                                                             case eArrayOfInteger:
  775.                                                                 Data = IntegerToString(((long*)Array)[Scan]);
  776.                                                                 break;
  777.                                                             case eArrayOfFixed:
  778.                                                                 Data = LongDoubleToString(largefixed2double(
  779.                                                                     ((largefixedsigned*)Array)[Scan]),11,1e-9,1e6);
  780.                                                                 break;
  781.                                                             case eArrayOfFloat:
  782.                                                                 Data = LongDoubleToString(((float*)
  783.                                                                     Array)[Scan],7,1e-4,1e6);
  784.                                                                 break;
  785.                                                             case eArrayOfDouble:
  786.                                                                 Data = LongDoubleToString(((double*)
  787.                                                                     Array)[Scan],15,1e-4,1e6);
  788.                                                                 break;
  789.                                                             default:
  790.                                                                 EXECUTE(PRERR(ForceAbort,
  791.                                                                     "CalculatorWindowDoCalculation:  type filter failure"));
  792.                                                                 break;
  793.                                                         }
  794.                                                     if (Data != NIL)
  795.                                                         {
  796.                                                             char*                LineNumCopy;
  797.  
  798.                                                             if (PtrSize(LineNum) > 16 - 1)
  799.                                                                 {
  800.                                                                     LineNumCopy = CopyPtr(LineNum);
  801.                                                                 }
  802.                                                              else
  803.                                                                 {
  804.                                                                     long                Index;
  805.  
  806.                                                                     LineNumCopy = AllocPtrCanFail(16,"LineNumCopy");
  807.                                                                     if (LineNumCopy != NIL)
  808.                                                                         {
  809.                                                                             for (Index = 0; Index < 16; Index += 1)
  810.                                                                                 {
  811.                                                                                     LineNumCopy[Index] = 32;
  812.                                                                                 }
  813.                                                                             CopyData(LineNum,LineNumCopy,PtrSize(LineNum));
  814.                                                                             LineNumCopy[PtrSize(LineNum)] = ':';
  815.                                                                         }
  816.                                                                 }
  817.                                                             if (LineNumCopy != NIL)
  818.                                                                 {
  819.                                                                     char*                    Total;
  820.  
  821.                                                                     Total = ConcatBlockCopy(LineNumCopy,Data);
  822.                                                                     if (Total != NIL)
  823.                                                                         {
  824.                                                                             TextEditAppendLineInteraction(Window->Editor,Total);
  825.                                                                             ReleasePtr(Total);
  826.                                                                         }
  827.                                                                      else
  828.                                                                         {
  829.                                                                             MemoryErrorOccurred = True;
  830.                                                                         }
  831.                                                                     ReleasePtr(LineNumCopy);
  832.                                                                 }
  833.                                                              else
  834.                                                                 {
  835.                                                                     MemoryErrorOccurred = True;
  836.                                                                 }
  837.                                                             ReleasePtr(Data);
  838.                                                         }
  839.                                                      else
  840.                                                         {
  841.                                                             MemoryErrorOccurred = True;
  842.                                                         }
  843.                                                     ReleasePtr(LineNum);
  844.                                                 }
  845.                                              else
  846.                                                 {
  847.                                                     MemoryErrorOccurred = True;
  848.                                                 }
  849.                                         }
  850.                                 }
  851.                         }
  852.                      else
  853.                         {
  854.                             MemoryErrorOccurred = True;
  855.                         }
  856.                     break;
  857.             }
  858.         /* add final terminating thing */
  859.         TextEditAppendLineInteraction(Window->Editor,NIL);
  860.         TextEditShowSelection(Window->Editor);
  861.         if (MemoryErrorOccurred)
  862.             {
  863.                 AlertHalt("There is not enough memory available to completely display the "
  864.                     "results of evaluating the function.",NIL);
  865.             }
  866.  
  867.         /* remember new last line */
  868.         Window->LastLine = GetTextEditNumLines(Window->Editor) - 1;
  869.  
  870.         /* dispose of stuff */
  871.         DisposeParamStack(ParamList);
  872.         DisposePcode(FuncCode);
  873.     }
  874.